#!/usr/bin/env python
# -*- coding: utf-8 -*-

from typing import List, Dict, Any, Optional, Tuple

from app.core.logging import get_logger, LoggerMixin
from app.core.exceptions import NotFoundError, DatabaseError
from app.repositories.project import ProjectRepository
from app.models.database import Project

# 创建日志记录器
logger = get_logger("project_service")


class ProjectService(LoggerMixin):
    """项目服务
    
    管理项目相关业务逻辑
    """
    
    def __init__(self, project_repo: ProjectRepository):
        """初始化项目服务
        
        Args:
            project_repo: 项目仓库
        """
        self.project_repo = project_repo
    
    async def create_project(
        self,
        name: str,
        description: Optional[str] = None
    ) -> Dict[str, Any]:
        """创建项目
        
        Args:
            name: 项目名称
            description: 项目描述
            
        Returns:
            Dict[str, Any]: 创建的项目数据
            
        Raises:
            DatabaseError: 当创建失败时
        """
        try:
            # 创建项目
            project_dict = await self.project_repo.create(name, description)
            project_id = project_dict['id']
            self.logger.info(f"已创建项目: {project_id}")
            
            # 初始化向量集合
            try:
                from app.repositories.vector import VectorRepository
                from app.repositories.milvus import milvus_client
                
                vector_repo = VectorRepository(milvus_client)
                await vector_repo.ensure_collections(project_id)
                self.logger.info(f"已为项目 {project_id} 初始化向量集合")
            except Exception as e:
                self.logger.error(f"初始化向量集合失败: {str(e)}")
                # 不抛出异常，继续返回项目
            
            return project_dict
        except Exception as e:
            self.logger.error(f"创建项目失败: {str(e)}")
            raise
    
    async def get_project(self, project_id: str) -> Dict[str, Any]:
        """获取项目
        
        Args:
            project_id: 项目ID
            
        Returns:
            Dict[str, Any]: 项目数据
            
        Raises:
            NotFoundError: 当项目不存在时
        """
        try:
            project_dict = await self.project_repo.get_by_id(project_id)
            return project_dict
        except Exception as e:
            self.logger.error(f"获取项目失败: {str(e)}")
            raise
    
    async def update_project(
        self,
        project_id: str,
        name: Optional[str] = None,
        description: Optional[str] = None
    ) -> Dict[str, Any]:
        """更新项目
        
        Args:
            project_id: 项目ID
            name: 项目名称
            description: 项目描述
            
        Returns:
            Dict[str, Any]: 更新后的项目数据
            
        Raises:
            NotFoundError: 当项目不存在时
            DatabaseError: 当更新失败时
        """
        try:
            project_dict = await self.project_repo.update(project_id, name, description)
            self.logger.info(f"已更新项目: {project_id}")
            return project_dict
        except Exception as e:
            self.logger.error(f"更新项目失败: {str(e)}")
            raise
    
    async def delete_project(self, project_id: str) -> None:
        """删除项目
        
        Args:
            project_id: 项目ID
            
        Raises:
            NotFoundError: 当项目不存在时
            DatabaseError: 当删除失败时
        """
        try:
            await self.project_repo.delete(project_id)
            self.logger.info(f"已删除项目: {project_id}")
        except Exception as e:
            self.logger.error(f"删除项目失败: {str(e)}")
            raise
    
    async def list_projects(
        self,
        limit: int = 10,
        offset: int = 0
    ) -> Tuple[List[Dict[str, Any]], int]:
        """列出项目
        
        Args:
            limit: 限制数量
            offset: 偏移量
            
        Returns:
            Tuple[List[Dict[str, Any]], int]: 项目列表和总数
            
        Raises:
            DatabaseError: 当查询失败时
        """
        try:
            project_dicts, total = await self.project_repo.list_all(limit, offset)
            return project_dicts, total
        except Exception as e:
            self.logger.error(f"列出项目失败: {str(e)}")
            raise